/**
	Pulsar engine. Additional include file.
	Threads and jobs support.

	Copyright (C) 2013-2014 Dmitry Dolgov

	This program is free software; you can redistribute it and/or modify it under the terms of the
	GNU General Public License as published by the Free Software Foundation; either version 2 of
	the License, or (at your option) any later version.

	This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY;
	without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
	See the GNU General Public License for more details.
*/

namespace pl
{

/// Inifinite waiting time for wait() functions
const pl_int32 WAIT_INFINITE = 0xFFFFFFFF;

class ThreadHandler;
struct _Job;

/**
	List of standard thread priority
*/
enum ThreadPrior
{
	/// Low proority (idle)
	THREAD_PRIOR_IDLE,
	/// Low proority
	THREAD_PRIOR_LOW,
	/// Regular priority
	THREAD_PRIOR_NORMAL,
	/// High priority
	THREAD_PRIOR_HIGH,
	/// Realtime priority
	THREAD_PRIOR_MAX
};

class Thread
{
public:

	/// New thread ctor
	explicit Thread(int queueSize = 0, int stackSize = 0, const pl_char* name = NULL);

	/// dtor
	~Thread();

	/// Setup thread affinity mask
	bool setProcessor(int index);

	/// Setup thread priority
	bool setPriority(ThreadPrior prior, int order);

	/// Push task to queue
	bool queueTask(const pl::Function<void()>& cb);
	bool queueTask(const pl::Function<void(pl_int64)>& cb, int value);
	bool queueTask(const pl::Function<void(void*)>& cb, void* ptr);
	bool queueTask(const pl::Function<void(pl_int64, pl_int64)>& cb, pl_int64 arg1, pl_int64 arg2);
	bool queueTask(const pl::Function<void(void*, pl_int64)>& cb, void* ptr, pl_int64 arg1);

	/// Wait thread idle state
	bool wait(pl_int32 timeoutMs);

	/// Get thread id
	pl_uintptr getThreadId();

	/// Internal usage only
	void _threadProc();

private:
	bool _queueTask(const _Job& job);


	int _queueSize;                // Max munber of tasks in list
	QueueBase _tasksQueue;         // Task queueu
	Semaphore _semaQueue;          // Queue semaphore (not empty queue)
	Semaphore _semaExit;           // Ready to exit semaphore
	ThreadHandler* _threadHandler; // OS-spec thread handler
	pl::String<64> _name;          // Debug thread name
};

//
// Common functions
//
extern pl_uintptr getThreadId();
extern pl_uintptr getThreadCount();
extern pl_uintptr getProcessId();
extern void sleepMs(pl_uint32 timeMs);
extern pl_uint32 getTimeMS();
extern pl_float getTimeSec();


} // namespace pl

//
// End of file 'pulsar_thread.h'
//
